/*
  通用的接口调用方法
*/
import axios from 'axios'
import store from '@/store/index.js'
import router from '@/router/index.js'
import JSONBIGINT from 'json-bigint'
// import { createNamespacedHelpers } from 'vuex'
// createNamespacedHelpers的参数是模块的名称
// const { mapState } = createNamespacedHelpers('login')
// mapState(['userInfo']).userInfo

const baseURL = 'http://api-toutiao-web.itheima.net/'

// 创建专门的axios请求实例对象
const instance = axios.create({
  baseURL: baseURL,
  // 配置返回数据的格式
  transformResponse: [(data) => {
    // data参数表示后端返回的原始数据
    try {
      return JSONBIGINT.parse(data)
    } catch (e) {
      console.log(e)
      // 这里表示如果转换错误，那么就返回原始数据（不做转换）
      return data
    }
  }]
})

// 请求拦截器
instance.interceptors.request.use((config) => {
  // 统一添加请求头（登录成功后添加）
  // store中的状态 -> 模块名称 --> 状态属性
  // store.state.login.userInfo
  const userInfo = store.state.login.userInfo
  if (userInfo && userInfo.token) {
    // 登录成功，添加请求头
    config.headers.authorization = 'Bearer ' + userInfo.token
  }
  return config
}, (err) => {
  return Promise.reject(err)
})

// 响应拦截器
instance.interceptors.response.use((response) => {
  return response.data
}, async (err) => {
  if (err.response.status === 401) {
    try {
      // 获取用户的token信息
      const userInfo = store.state.login.userInfo
      // token失效了，通过refreshtoken申请一个新的token
      const ret = await axios.put(baseURL + 'app/v1_0/authorizations', null, {
        headers: {
          authorization: 'Bearer ' + userInfo.refresh_token
        }
      })
      // 替换之前的token,触发mutation
      userInfo.token = ret.data.data.token
      store.commit('login/updateUserInfo', userInfo)
      // 把刚才失败的请求用新的token再重新发送
      return instance(err.config)
    } catch (e) {
      console.log(e)
      // 跳转到登录页面，删除用户信息
      store.commit('login/deleteUserInfo')
      router.push('/login')
    }
  }
  return Promise.reject(err)
})

// 封装通用的接口调用方法
export default (options) => {
  return instance({
    method: options.method || 'get',
    url: options.url || '#',
    data: options.data,
    params: options.params,
    headers: options.headers
  })
}
